;disassembly from FCEUXD. Ignore the = and @ stuff $F540:A4 88 LDY $STRING_INDEX = #$00 $F542:20 50 F5 JSR $F550 ;do dictionary/DTE stuff $F545:60 RTS $F546:FF UNDEFINED ;padding so that the code lines up in a hex editor $F547:FF UNDEFINED $F548:FF UNDEFINED $F549:FF UNDEFINED $F54A:FF UNDEFINED $F54B:FF UNDEFINED $F54C:FF UNDEFINED $F54D:FF UNDEFINED $F54E:FF UNDEFINED $F54F:FF UNDEFINED $F550:8A TXA ;save X's value for when we return to the game code $F551:48 PHA $F552:C0 00 CPY #$00 ;first character in the string? $F554:D0 04 BNE $F55A ;NOT FIRST CHAR $F556:A9 00 LDA #$00 ;if so, initialize the DTE/dictionary flag $F558:85 C0 STA $DICT_OFFSET_HIGH = #$00 NOT FIRST CHAR: $F55A:A5 C0 LDA $DICT_OFFSET_HIGH = #$00 ;check the low 7 bits of dictionary offset $F55C:29 7F AND #$7F $F55E:F0 03 BEQ $F563 ;if 0, we are not processing a dictionary entry $F560:4C F4 F5 JMP $F5F4 ;DICTIONARY NOT DICTIONARY: $F563:A5 C0 LDA $DICT_OFFSET_HIGH = #$00 ;check the DTE flag, which is the highest bit of the first byte of the ;dictionary offset $F565:29 80 AND #$80 $F567:D0 25 BNE $F58E ;if the result is not equal, then DTE = 1 = do SECOND PASS $F569:B1 1C LDA ($SCRIPT),Y @ $4000 = #$FF ;read a byte of the game script $F56B:C9 9F CMP #$DICTIONARY_FLAG ;if byte read is a dictionary key $F56D:D0 03 BNE $F572 $F56F:4C B0 F5 JMP $F5B0 ;process dictionary entry (goto DICTIONARY) $F572:C9 A0 CMP #$DTE_UPPER_BOUND ;if byte >= (1 higher than the last DTE entry) $F574:B0 32 BCS $F5A8 ;go to SINGLE TILE $F576:C9 10 CMP #$DTE_LOWER_BOUND ;if byte < (lowest value of DTE entry) $F578:90 2E BCC $F5A8 ;go to SINGLE TILE $F57A:38 SEC $F57B:E9 10 SBC #$DTE_LOWER_BOUND ;translate byte code into index in DTE table $F57D:AA TAX ;X = entry in DTE table $F57E:BD 00 FF LDA $DTE_FIRST_BYTE,X ;read table of the first character in each DTE pair $F581:85 C2 STA $SCRIRT_REPLACE = #$00 ;value to replace last read script byte with $F583:A5 C0 LDA $DICT_OFFSET_HIGH = #$00 $F585:09 80 ORA #$80 $F587:85 C0 STA $DICT_OFFSET_HIGH = #$00 $F589:68 PLA ;restore the value of X from before the routine. $F58A:AA TAX $F58B:A5 C2 LDA $SCRIRT_REPLACE = #$00 ;load our value from the DTE table $F58D:60 RTS SECOND PASS: $F58E:C6 88 DEC $STRING_INDEX = #$00 ;decrement STRING_INDEX $F590:A4 88 LDY $STRING_INDEX = #$00 ;so we can read the same byte of the script $F592:B1 1C LDA ($SCRIPT),Y @ $4000 = #$FF ;as was read in the first pass $F594:38 SEC $F595:E9 10 SBC #$DTE_LOWER_BOUND $F597:AA TAX $F598:BD 7D FF LDA $DTE_SECOND_BYTE,X ;read table of the second character in each DTE pair $F59B:85 C2 STA $SCRIRT_REPLACE = #$00 $F59D:A5 C0 LDA $DICT_OFFSET_HIGH = #$00 ;turn off the DTE second pass flag $F59F:29 7F AND #$7F ;by zero-ing the highest bit of the first byte of the DICT_OFF $F5A1:85 C0 STA $DICT_OFFSET_HIGH = #$00 $F5A3:68 PLA ;we restore the value of X from before the routine $F5A4:AA TAX $F5A5:A5 C2 LDA $SCRIRT_REPLACE = #$00 ;load our value from the DTE table $F5A7:60 RTS SINGLE TILE: $F5A8:85 C2 STA $SCRIRT_REPLACE = #$00 ;A was the value we last read from the script $F5AA:68 PLA $F5AB:AA TAX $F5AC:A5 C2 LDA $SCRIRT_REPLACE = #$00 $F5AE:60 RTS $F5AF:FF UNDEFINED ;padding DICTIONARY: $F5B0:E6 88 INC $STRING_INDEX = #$00 ;increment STRING_INDEX to the next byte of the script $F5B2:A4 88 LDY $STRING_INDEX = #$00 $F5B4:A2 00 LDX #$00 $F5B6:B1 1C LDA ($SCRIPT),Y @ $4000 = #$FF ;get the dictionary entry $F5B8:85 C2 STA $SCRIRT_REPLACE = #$00 $F5BA:EA NOP $F5BB:A9 00 LDA #$LOW_BYTE_OF_DICTIONARY_OFFSET ;set the high byte of the dictionary entry $F5BD:85 C0 STA $DICT_OFFSET_HIGH = #$00 $F5BF:A9 F7 LDA #$HIGH_BYTE_OF_DICTIONARY_OFFSET $F5C1:85 C1 STA $DICT_OFFSET_LOW = #$00 $F5C3:A0 00 LDY #$00 WANTED ENTRY CHECK: $F5C5:A5 C2 LDA $SCRIRT_REPLACE = #$00 ;read dictionary entry $F5C7:F0 1C BEQ $F5E5 ;if 0, we have found the desired dictionary entry. ;Now PROCESS ENTRY DICTIONARY ENTRY OFFSET SEARCH: $F5C9:B1 C0 LDA ($DICT_OFFSET_HIGH),Y @ $0000 = #$00 ;read the dictionary $F5CB:C9 FF CMP #$STRING_END ;check if we've reached the end of an entry $F5CD:F0 0A BEQ $F5D9 ;if so, go to END OF AN ENTRY $F5CF:18 CLC $F5D0:E6 C0 INC $DICT_OFFSET_HIGH = #$00 ;increment the dictionary read offset, low byte $F5D2:90 02 BCC $F5D6 ;if we overflow the low byte, $F5D4:E6 C1 INC $DICT_OFFSET_LOW = #$00 ;increment the high byte (I think this might be a bug. ;Might have to replace ;BCC with LDA DICT_OFFSET_HIGH : BNE. $F5D6:4C C9 F5 JMP $F5C9 ;DICTIONARY ENTRY OFFSET SEARCH END OF AN ENTRY: $F5D9:18 CLC $F5DA:E6 C0 INC $DICT_OFFSET_HIGH = #$00 ;again, routine to increment the dictionary pointer $F5DC:90 02 BCC $F5E0 $F5DE:E6 C1 INC $DICT_OFFSET_LOW = #$00 $F5E0:C6 C2 DEC $SCRIRT_REPLACE = #$00 ;decrement the dictionary index $F5E2:4C C5 F5 JMP $F5C5 ;WANTED ENTRY CHECK PROCESS ENTRY: $F5E5:A5 C0 LDA $DICT_OFFSET_HIGH = #$00 ;save the dictionary offset low byte $F5E7:48 PHA $F5E8:A5 C1 LDA $DICT_OFFSET_LOW = #$00 ;this part is where we want to flip the low byte ;and high byte $F5EA:38 SEC $F5EB:E9 F6 SBC #$HIGH_BYTE_OF_DICT_TABLE_OFFSET-1 ;set the offset of the dictionary entry to be relative to $F5ED:85 C0 STA $DICT_OFFSET_HIGH = #$00 ;the start of the dictionary table, and set the ;high byte to a minimum ;of 1 as a dictionary flag $F5EF:68 PLA ;to ensure dictionary is processed $F5F0:85 C1 STA $DICT_OFFSET_LOW = #$00 DICTIONARY ROUTINE: $F5F4:C6 88 DEC $STRING_INDEX = #$00 ;re-same dictionary index value each time $F5F6:A5 C0 LDA $DICT_OFFSET_HIGH = #$00 ;check if the dictionary string is on the second ;pass of a DTE code $F5F8:29 80 AND #$80 $F5FA:F0 03 BEQ $F5FF $F5FC:4C 60 F6 JMP $F660 ;go to DICTIONARY DTE SECOND PASS $F5FF:98 TYA ;save previous Y $F600:48 PHA $F601:A5 C0 LDA $DICT_OFFSET_HIGH = #$00 $F603:48 PHA $F604:A5 C1 LDA $DICT_OFFSET_LOW = #$00 $F606:48 PHA $F607:A5 C0 LDA $DICT_OFFSET_HIGH = #$00 ;clear the DTE flag, translate dictionary offset back $F609:29 7F AND #$7F ;to absolute, and subtract 1 to counter ;the dictionary flag $F60B:18 CLC $F60C:69 F6 ADC #$HIGH_BYTE_OF_DICT_TABLE_OFFSET-1 $F60E:85 C1 STA $DICT_OFFSET_LOW = #$00 ;flip the bytes so that the low byte comes first $F610:68 PLA $F611:85 C0 STA $DICT_OFFSET_HIGH = #$00 $F613:48 PHA $F614:A0 00 LDY #$00 $F616:B1 C0 LDA ($DICT_OFFSET_HIGH),Y @ $0000 = #$00 ;read the dictionary $F618:85 C2 STA $SCRIRT_REPLACE = #$00 ;store the value read from the dictionary $F61A:68 PLA $F61B:85 C1 STA $DICT_OFFSET_LOW = #$00 ;restore the old dictionary pointer $F61D:68 PLA ;(DTE flag+7 high bits, followed by low 8 bits) $F61E:85 C0 STA $DICT_OFFSET_HIGH = #$00 $F620:68 PLA $F621:A8 TAY $F622:18 CLC ;increment dictionary pointer $F623:E6 C1 INC $DICT_OFFSET_LOW = #$00 $F625:90 02 BCC $F629 $F627:E6 C0 INC $DICT_OFFSET_HIGH = #$00 $F629:A5 C2 LDA $SCRIRT_REPLACE = #$00 ;check if this is the end of the dictionary string $F62B:C9 FF CMP #$STRING_END $F62D:D0 03 BNE $F632 $F62F:4C 50 F6 JMP $F650 ;if so, go to END DICTIONARY STRING $F632:C9 A0 CMP #$DTE_UPPER_BOUND+1 $F634:B0 0F BCS $F645 ;if higher than the upper bound of the DTE range, go to DICT SINGLE ;(since all code below the lower bound is controls, this code assumes ; the dictionary strings do not contain control codes, thus are not below ; the lower bound) $F636:A5 C0 LDA $DICT_OFFSET_HIGH = #$00 ;turns on the DTE second pass flag $F638:09 80 ORA #$80 $F63A:85 C0 STA $DICT_OFFSET_HIGH = #$00 $F63C:A5 C2 LDA $SCRIRT_REPLACE = #$00 ;load the byte read from the dictionary string $F63E:38 SEC $F63F:E9 10 SBC #$10 ;turn it into a DTE index $F641:AA TAX $F642:BD 00 FF LDA $DTE_FIRST_BYTE,X ;read the table of first characters in each DTE pair DICT SINGLE: $F645:85 C2 STA $SCRIRT_REPLACE = #$00 ;the character to output to the text display buffer $F647:EA NOP ;nothing. I pobably deleted some bug here. $F648:68 PLA ;restore the X from before the routine $F649:AA TAX $F64A:A5 C2 LDA $SCRIRT_REPLACE = #$00 ;load the character to be sent to the text buffer $F64C:A4 88 LDY $STRING_INDEX = #$00 ;reload the index to the main string $F64E:60 RTS $F64F:FF UNDEFINED ;padding END DICTIONARY STRING: $F650:A9 00 LDA #$00 ;thus turns off the DTE second pass and dictionary flags $F652:85 C0 STA $DICT_OFFSET_HIGH = #$00 $F654:85 C1 STA $DICT_OFFSET_LOW = #$00 $F656:E6 88 INC $STRING_INDEX = #$00 ;increase string index by 2, since the dictionary code is 2 bytes $F658:E6 88 INC $STRING_INDEX = #$00 $F65A:A4 88 LDY $STRING_INDEX = #$00 ;load the updated string index $F65C:4C 69 F5 JMP $F569 ;go way back up in the code to where we first checked the dictionary flag $F65F:FF UNDEFINED DICTIONARY DTE SECOND PASS: $F660:C6 C1 DEC $DICT_OFFSET_LOW = #$00 ;decrement the dictionary pointer $F662:B0 02 BCS $F666 ;skip if the low byte did not underflow ;again, this code may be buggy. Better to probably LDA $DICT_OFFSET_LOW ;CMP #$FF : BNE $02 : DEC $DIRECT_OFFSET_HIGH to be sure $F664:C6 C0 DEC $DICT_OFFSET_HIGH = #$00 $F666:A5 C0 LDA $DICT_OFFSET_HIGH = #$00 $F668:48 PHA $F669:A5 C1 LDA $DICT_OFFSET_LOW = #$00 $F66B:48 PHA $F66C:A5 C0 LDA $DICT_OFFSET_HIGH = #$00 ;like the first pass, this swaps the bytes and converts to an absolute $F66E:29 7F AND #$7F ;address $F670:18 CLC $F671:69 F6 ADC #$F6 $F673:85 C1 STA $DICT_OFFSET_LOW = #$00 $F675:68 PLA $F676:85 C0 STA $DICT_OFFSET_HIGH = #$00 $F678:48 PHA $F679:A0 00 LDY #$00 $F67B:B1 C0 LDA ($DICT_OFFSET_HIGH),Y @ $0000 = #$00 ;read the dictionary $F67D:85 C2 STA $SCRIRT_REPLACE = #$00 ;store character fread from dictionary $F67F:68 PLA $F680:85 C1 STA $DICT_OFFSET_LOW = #$00 $F682:68 PLA $F683:85 C0 STA $DICT_OFFSET_HIGH = #$00 ;restore previous DTE/dictionary flags $F685:A5 C2 LDA $SCRIRT_REPLACE = #$00 ;load character read from dictionary $F687:38 SEC $F688:E9 10 SBC #$10 ;convert to DTE index $F68A:AA TAX $F68B:BD 7D FF LDA $DTE_SECOND_BYTE,X ;read table of second character in each DTE pair $F68E:48 PHA $F68F:A5 C0 LDA $DICT_OFFSET_HIGH = #$00 ;turn DTE second pass flag off $F691:29 7F AND #$7F $F693:85 C0 STA $DICT_OFFSET_HIGH = #$00 $F695:68 PLA $F696:85 C2 STA $SCRIRT_REPLACE = #$00 ;store character read from SECOND BYTE table $F698:68 PLA $F699:AA TAX ;restore X from before the routine $F69A:A5 C2 LDA $SCRIRT_REPLACE = #$00 ;load character read from SECOND BYTE table $F69C:A4 88 LDY $STRING_INDEX = #$00 ;restore STRING INDEX $F69E:18 CLC $F69F:E6 C1 INC $DICT_OFFSET_LOW = #$00 ;increment dictionary pointer $F6A1:90 02 BCC $F6A5 $F6A3:E6 C0 INC $DICT_OFFSET_HIGH = #$00 $F6A5:60 RTS